package com.telrob.bytevm.instruct;

import java.util.List;

import com.telrob.bytevm.compile.Instruct;
import com.telrob.bytevm.compile.ReplaceCode;
import com.telrob.bytevm.utils.Define;
import com.telrob.bytevm.utils.ToolUtils;
import com.telrob.bytevm.vm.Register;

public class CMP implements Instruct {

	public boolean isPseudo(String opt) {
		return false;
	}

	public boolean isComplie(String opt) {
		if("cmprr".equals(opt.toLowerCase())||"cmprn".equals(opt.toLowerCase())) {
			return true;
		}
		return false;
	}

	@Override
	public byte[] complie(String line, String[] param, int curretIndex, List<ReplaceCode> labelReplace) {
		byte[]data=null;
		//寄存器相比
		if("cmprr".equals(param[0].toLowerCase())) {
			data=new byte[3];
			data[0]=Define.CMPRR;
			String o2=param[1].toLowerCase();
			if("ax".equals(o2)) {
				data[1]=Define.AX;
			}else if("bx".equals(o2)) {
				data[1]=Define.BX;
			}else if("cx".equals(o2)) {
				data[1]=Define.CX;
			}else if("dx".equals(o2)) {
				data[1]=Define.DX;
			}else if("ex".equals(o2)) {
				data[1]=Define.EX;
			}else if("ss".equals(o2)) {
				data[1]=Define.SS;
			}else if("si".equals(o2)) {
				data[1]=Define.SI;
			}else if("sp".equals(o2)) {
				data[1]=Define.SP;
			}else if("bp".equals(o2)) {
				data[1]=Define.BP;
			}else if("di".equals(o2)) {
				data[1]=Define.DI;
			}
			String o3=param[2].toLowerCase();
			if("ax".equals(o3)) {
				data[2]=Define.AX;
			}else if("bx".equals(o3)) {
				data[2]=Define.BX;
			}else if("cx".equals(o3)) {
				data[2]=Define.CX;
			}else if("dx".equals(o3)) {
				data[2]=Define.DX;
			}else if("ex".equals(o3)) {
				data[2]=Define.EX;
			}else if("ss".equals(o3)) {
				data[2]=Define.SS;
			}else if("si".equals(o3)) {
				data[2]=Define.SI;
			}else if("sp".equals(o3)) {
				data[2]=Define.SP;
			}else if("bp".equals(o3)) {
				data[2]=Define.BP;
			}else if("di".equals(o3)) {
				data[2]=Define.DI;
			}
		}else if("cmprn".equals(param[0].toLowerCase())) {
			data=new byte[6];
			data[0]=Define.CMPRN;
			String o2=param[1].toLowerCase();
			if("ax".equals(o2)) {
				data[1]=Define.AX;
			}else if("bx".equals(o2)) {
				data[1]=Define.BX;
			}else if("cx".equals(o2)) {
				data[1]=Define.CX;
			}else if("dx".equals(o2)) {
				data[1]=Define.DX;
			}else if("ex".equals(o2)) {
				data[1]=Define.EX;
			}else if("ss".equals(o2)) {
				data[1]=Define.SS;
			}else if("si".equals(o2)) {
				data[1]=Define.SI;
			}else if("sp".equals(o2)) {
				data[1]=Define.SP;
			}else if("bp".equals(o2)) {
				data[1]=Define.BP;
			}else if("di".equals(o2)) {
				data[1]=Define.DI;
			}
			int number=ToolUtils.parseNum(param[2]);
			data[2]=(byte)(0xFF&(number>>0));
			data[3]=(byte)(0xFF&(number>>8));
			data[4]=(byte)(0xFF&(number>>16));
			data[5]=(byte)(0xFF&(number>>24));
		}
		return data;
	}

	public int isRun(byte opt) {
		if(opt==Define.CMPRR) {
			return 3;
		}else if(opt==Define.CMPRN) {
			return 6;
		}
		return -1;
	}

	@Override
	public void parseRun(Register R, byte opt, byte[] data) {
		if(opt==Define.CMPRR) {
			byte rx=data[R.PC+1];
			byte rx2=data[R.PC+2];
			int number1=0;
			int number2=0;
			if(rx==Define.AX) {
				number1=R.AX;
			}else if(rx==Define.BX) {
				number1=R.BX;
			}else if(rx==Define.CX) {
				number1=R.CX;
			}else if(rx==Define.DX) {
				number1=R.DX;
			}else if(rx==Define.EX) {
				number1=R.EX;
			}else if(rx==Define.BP) {
				number1=R.BP;
			}else if(rx==Define.SS) {
				number1=R.SS;
			}else if(rx==Define.SP) {
				number1=R.SP;
			}
			if(rx2==Define.AX) {
				number2=R.AX;
			}else if(rx2==Define.BX) {
				number2=R.BX;
			}else if(rx2==Define.CX) {
				number2=R.CX;
			}else if(rx2==Define.DX) {
				number2=R.DX;
			}else if(rx2==Define.EX) {
				number2=R.EX;
			}else if(rx2==Define.BP) {
				number2=R.BP;
			}else if(rx2==Define.SS) {
				number2=R.SS;
			}else if(rx2==Define.SP) {
				number2=R.SP;
			}
			R.CX=number1-number2;
			R.PC+=isRun(opt);
		}else if(opt==Define.CMPRN) {
			byte rx=data[R.PC+1];
			int number1=0;
			int number2=0;
			if(rx==Define.AX) {
				number1=R.AX;
			}else if(rx==Define.BX) {
				number1=R.BX;
			}else if(rx==Define.CX) {
				number1=R.CX;
			}else if(rx==Define.DX) {
				number1=R.DX;
			}else if(rx==Define.EX) {
				number1=R.EX;
			}else if(rx==Define.BP) {
				number1=R.BP;
			}else if(rx==Define.SS) {
				number1=R.SS;
			}else if(rx==Define.SP) {
				number1=R.SP;
			}
			number2=ToolUtils.getInt(data, R.PC+2);
			R.CX=number1-number2;
			R.PC+=isRun(opt);
		}
	}

}
